package com.company.huisuo.widget

import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import kotlin.math.abs

/**
 * 自定义卡片堆叠LayoutManager
 * 实现3D卡片效果：中间卡片最大，两侧依次缩小并倾斜
 */
class CardStackLayoutManager : RecyclerView.LayoutManager() {

    // 可见卡片数量（中间1张+左右各3张）
    private val visibleCount = 7

    // 卡片间距
    private val cardSpacing = 20

    // 最小缩放比例
    private val minScale = 0.75f

    // 每个单位距离的缩放减少量
    private val scaleStep = 0.08f

    // 每个单位距离的旋转增加量
    private val rotationStep = 5f

    // 滚动偏移量（浮点数，支持更精确的滚动）
    private var scrollOffset = 0f

    // 每个item的宽度
    private var itemWidth = 0

    // 实际item数量（如10张卡片）
    private var realItemCount = 10

    // 是否允许用户手动滑动
    var canUserScroll = false

    override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams {
        return RecyclerView.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT
        )
    }

    override fun onLayoutChildren(recycler: RecyclerView.Recycler, state: RecyclerView.State) {
        if (itemCount == 0) {
            detachAndScrapAttachedViews(recycler)
            return
        }

        detachAndScrapAttachedViews(recycler)

        // 更新实际item数量
        realItemCount = itemCount

        // 计算item宽度
        if (itemWidth == 0) {
            val tempView = recycler.getViewForPosition(0)
            addView(tempView)
            measureChildWithMargins(tempView, 0, 0)
            itemWidth = getDecoratedMeasuredWidth(tempView)
            detachAndScrapView(tempView, recycler)
        }

        layoutItems(recycler)
    }

    /**
     * 布局所有可见的item
     */
    private fun layoutItems(recycler: RecyclerView.Recycler) {
        val centerX = width / 2
        val centerY = height / 2

        // 计算中心位置的逻辑索引（可以是任意大的数字）
        val centerLogicalPosition = scrollOffset / (itemWidth + cardSpacing)

        // 布局可见范围内的item
        val startLogicalPos = (centerLogicalPosition - visibleCount / 2).toInt()
        val endLogicalPos = (centerLogicalPosition + visibleCount / 2 + 1).toInt()

        for (logicalPos in startLogicalPos until endLogicalPos) {
            // 通过模运算获取实际位置，实现循环
            val actualPosition = ((logicalPos % realItemCount) + realItemCount) % realItemCount

            val view = recycler.getViewForPosition(actualPosition)
            addView(view)
            measureChildWithMargins(view, 0, 0)

            val itemHeight = getDecoratedMeasuredHeight(view)

            // 计算该item相对于中心的偏移
            val itemLogicalOffset = logicalPos * (itemWidth + cardSpacing).toFloat()
            val distanceFromCenter = itemLogicalOffset - scrollOffset

            // 计算卡片距离中心的位置索引（0表示在中心，1表示相邻，2表示再远一个...）
            val positionIndex = abs(distanceFromCenter) / (itemWidth + cardSpacing)

            // 计算缩放比例：每远离一个卡片位置，缩小scaleStep
            val scale = (1f - positionIndex * scaleStep).coerceIn(minScale, 1f)

            // 计算旋转角度：每远离一个卡片位置，增加rotationStep的旋转
            val rotation = if (distanceFromCenter > 0) {
                positionIndex * rotationStep
            } else {
                -positionIndex * rotationStep
            }

            // 设置变换效果
            view.scaleX = scale
            view.scaleY = scale
            view.rotationY = rotation
            // Z轴效果，中间的卡片在最上层
            view.translationZ = -abs(distanceFromCenter) * 0.1f

            // 计算位置
            val left = centerX - itemWidth / 2 + distanceFromCenter.toInt()
            val top = centerY - itemHeight / 2
            val right = left + itemWidth
            val bottom = top + itemHeight

            layoutDecorated(view, left, top, right, bottom)
        }
    }

    override fun canScrollHorizontally(): Boolean {
        return canUserScroll
    }

    override fun scrollHorizontallyBy(
        dx: Int,
        recycler: RecyclerView.Recycler,
        state: RecyclerView.State
    ): Int {
        if (!canUserScroll) return 0

        // 无限循环，不限制滚动范围
        scrollOffset += dx

        detachAndScrapAttachedViews(recycler)
        layoutItems(recycler)

        return dx
    }

    /**
     * 平滑滚动指定距离
     */
    fun smoothScrollBy(recyclerView: RecyclerView, distance: Int, duration: Long = 3000) {
        recyclerView.smoothScrollBy(distance, 0)
    }

    /**
     * 获取当前中心位置的item索引（实际位置0-9）
     */
    fun getCenterPosition(): Int {
        val centerLogicalPosition = (scrollOffset / (itemWidth + cardSpacing)).toInt()
        return ((centerLogicalPosition % realItemCount) + realItemCount) % realItemCount
    }

    /**
     * 获取当前滚动偏移量
     */
    fun getScrollOffset(): Float {
        return scrollOffset
    }

    /**
     * 设置滚动偏移量
     */
    fun setScrollOffset(offset: Float) {
        scrollOffset = offset
    }
}
